package com.example.demo.sensitive.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.demo.sensitive.dto.request.CheckTaskRequest;
import com.example.demo.sensitive.dto.response.CheckTaskResponse;
import com.example.demo.sensitive.entity.CheckTask;
import com.example.demo.sensitive.entity.SensitiveWord;
import com.example.demo.sensitive.mapper.CheckTaskMapper;
import com.example.demo.sensitive.mapper.SensitiveWordMapper;
import com.example.demo.sensitive.service.CheckTaskService;
import com.example.demo.sensitive.service.CheckResultService;
import com.example.demo.sensitive.entity.CheckResult;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Data;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import jakarta.annotation.PreDestroy;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @ClassName CheckTaskServiceImpl
 * @Description 检查任务服务实现类
 * @Author System
 * @Date 2025/9/19
 **/
@Service
public class CheckTaskServiceImpl extends ServiceImpl<CheckTaskMapper, CheckTask> implements CheckTaskService {

    private static final Log log = LogFactory.get();
    
    private final ObjectMapper objectMapper;
    private final ThreadPoolExecutor checkExecutor;
    // 用于跟踪运行中的任务，支持取消操作
    private final ConcurrentHashMap<Long, Future<?>> runningTasks = new ConcurrentHashMap<>();
    
    @Autowired
    private SensitiveWordMapper sensitiveWordMapper;
    
    @Autowired
    private CheckResultService checkResultService;

    public CheckTaskServiceImpl() {
        // 如果Spring没有自动配置ObjectMapper，手动创建一个
        this.objectMapper = new ObjectMapper();
        
        // 创建专用的检查任务线程池
        this.checkExecutor = new ThreadPoolExecutor(
            2, // 核心线程数
            10, // 最大线程数
            60L, TimeUnit.SECONDS, // 空闲线程存活时间
            new LinkedBlockingQueue<>(100), // 工作队列
            new ThreadFactory() {
                private final AtomicInteger threadNumber = new AtomicInteger(1);
                @Override
                public Thread newThread(Runnable r) {
                    Thread t = new Thread(r, "sensitive-check-" + threadNumber.getAndIncrement());
                    t.setDaemon(true); // 设置为守护线程
                    return t;
                }
            },
            new ThreadPoolExecutor.CallerRunsPolicy() // 拒绝策略：调用者执行
        );
    }

    @Override
    public Page<CheckTaskResponse> getPageList(int current, int size, String status, 
                                              LocalDateTime startTime, LocalDateTime endTime, String keyword) {
        // 查询分页数据，按创建时间倒序
        Page<CheckTask> page = new Page<>(current, size);
        page.addOrder(OrderItem.desc("create_time"));
        Page<CheckTask> result = baseMapper.selectPage(page, null);
        
        // 转换为响应对象
        Page<CheckTaskResponse> responsePage = new Page<>(current, size);
        responsePage.setTotal(result.getTotal());
        responsePage.setSize(result.getSize());
        responsePage.setCurrent(result.getCurrent());
        
        // 转换记录
        List<CheckTaskResponse> records = new ArrayList<>();
        for (CheckTask task : result.getRecords()) {
            records.add(convertToResponse(task));
        }
        responsePage.setRecords(records);
        
        return responsePage;
    }

    /**
     * 转换实体为响应对象
     */
    private CheckTaskResponse convertToResponse(CheckTask task) {
        CheckTaskResponse response = new CheckTaskResponse();
        
        // 使用Spring BeanUtils自动复制属性
        BeanUtils.copyProperties(task, response);
        
        // 特殊处理：将Long taskId转换为String，避免前端JavaScript精度丢失
        response.setTaskId(task.getTaskId() != null ? task.getTaskId().toString() : null);
        
        // 处理特殊字段：字符串转列表
        response.setSelectedTables(parseStringToList(task.getSelectedTables()));
        response.setSelectedKeywords(parseStringToList(task.getSelectedKeywords()));
        
        return response;
    }
    
    /**
     * 解析字符串为列表
     */
    private List<String> parseStringToList(String str) {
        if (str == null || str.trim().isEmpty()) {
            return new ArrayList<>();
        }
        
        // 尝试JSON格式
        if (str.startsWith("[") && str.endsWith("]")) {
            try {
                return objectMapper.readValue(str, objectMapper.getTypeFactory().constructCollectionType(List.class, String.class));
            } catch (Exception e) {
                // JSON解析失败，尝试逗号分隔
            }
        }
        
        // 逗号分隔格式
        String[] parts = str.split(",");
        List<String> result = new ArrayList<>();
        for (String part : parts) {
            String trimmed = part.trim();
            if (!trimmed.isEmpty()) {
                result.add(trimmed);
            }
        }
        return result;
    }

    @Override
    public CheckTaskResponse getById(Long id) {
        CheckTask entity = baseMapper.selectById(id);
        if (entity == null) {
            throw new RuntimeException("任务不存在");
        }
        
        return convertToResponse(entity);
    }

    @Override
    public Long createTask(CheckTaskRequest request) {
        CheckTask entity = new CheckTask();
        entity.setTaskName(request.getTaskName());
        entity.setDatabaseConfigId(request.getDatabaseId()); // 设置数据库配置ID
        
        // 设置选定的表（JSON格式）
        try {
            if (request.getTargetTables() != null && !request.getTargetTables().isEmpty()) {
                entity.setSelectedTables(objectMapper.writeValueAsString(request.getTargetTables()));
            } else {
                entity.setSelectedTables("[]"); // 空列表表示全量检查
            }
        } catch (Exception e) {
            throw new RuntimeException("序列化目标表列表失败", e);
        }
        
        // 设置选定的敏感词详细信息（JSON格式）
        try {
            if (request.getKeywordIds() != null && !request.getKeywordIds().isEmpty()) {
                // 直接使用注入的Mapper进行批量查询
                List<SensitiveWord> keywords = sensitiveWordMapper.selectByIds(request.getKeywordIds());
                
                // 创建简化的敏感词信息对象列表
                List<KeywordInfo> keywordInfos = new ArrayList<>();
                for (SensitiveWord keyword : keywords) {
                    KeywordInfo info = new KeywordInfo();
                    info.setId(keyword.getId());
                    info.setWord(keyword.getWord());
                    info.setCategory(keyword.getCategory());
                    info.setLevel(keyword.getLevel());
                    keywordInfos.add(info);
                }
                
                // 序列化为JSON存储
                entity.setSelectedKeywords(objectMapper.writeValueAsString(keywordInfos));
            } else {
                entity.setSelectedKeywords("[]");
            }
        } catch (Exception e) {
            throw new RuntimeException("序列化敏感词列表失败", e);
        }
        
        // 设置批处理大小
        if (request.getBatchSize() != null) {
            entity.setBatchSize(request.getBatchSize());
        }
        
        // 设置检查配置（如果有的话，转换为JSON字符串）
        try {
            if (request.getCheckConfig() != null) {
                entity.setCheckConfig(objectMapper.writeValueAsString(request.getCheckConfig()));
            }
        } catch (Exception e) {
            throw new RuntimeException("序列化检查配置失败", e);
        }
        
        entity.setCreateTime(LocalDateTime.now());
        
        log.debug("插入前的taskId: {}", entity.getTaskId());
        baseMapper.insert(entity);
        log.debug("插入后的taskId: {}", entity.getTaskId());
        
        // taskId 现在是Long 类型，直接返回
        Long taskId = entity.getTaskId();
        log.info("创建任务成功，taskId: {}", taskId);
        if (taskId > 9007199254740991L) {
            log.warn("JavaScript安全整数范围检查, taskId {} 超出安全范围", taskId);
        }
        return taskId;
    }

    @Override
    public void startTask(Long taskId) {
        CheckTask entity = baseMapper.selectById(taskId);
        if (entity != null) {
            entity.setStatus("RUNNING");
            entity.setStartTime(LocalDateTime.now());
            baseMapper.updateById(entity);
            
            log.info("任务启动成功，taskId: {}, 状态更新为: RUNNING", taskId);
            
            // 使用线程池异步执行真实的敏感词检查，并跟踪任务
            Future<?> taskFuture = checkExecutor.submit(() -> {
                try {
                    executeRealCheck(taskId);
                } catch (Exception e) {
                    // 处理异常，更新任务状态为失败
                    try {
                        CheckTask failedEntity = baseMapper.selectById(taskId);
                        if (failedEntity != null) {
                            failedEntity.setStatus("FAILED");
                            failedEntity.setEndTime(LocalDateTime.now());
                            failedEntity.setErrorMessage(e.getMessage());
                            baseMapper.updateById(failedEntity);
                            log.error("任务执行失败，taskId: {}, 错误: {}", taskId, e.getMessage());
                        }
                    } catch (Exception dbException) {
                        log.error("更新失败任务状态时出错，taskId: {}, 错误: {}", taskId, dbException.getMessage());
                    }
                } finally {
                    // 任务完成后从跟踪集合中移除
                    runningTasks.remove(taskId);
                }
            });
            
            // 将任务添加到跟踪集合
            runningTasks.put(taskId, taskFuture);
        }
    }

    @Override
    public void stopTask(Long taskId) {
        // 尝试取消正在运行的任务
        Future<?> taskFuture = runningTasks.get(taskId);
        if (taskFuture != null && !taskFuture.isDone()) {
            taskFuture.cancel(true); // 中断任务
            runningTasks.remove(taskId);
        }
        
        // 更新数据库状态
        CheckTask entity = baseMapper.selectById(taskId);
        if (entity != null) {
            entity.setStatus("STOPPED");
            entity.setEndTime(LocalDateTime.now());
            baseMapper.updateById(entity);
        }
    }

    @Override
    public void cancelTask(Long taskId) {
        // 先停止任务，然后删除
        stopTask(taskId);
        deleteTask(taskId);
    }

    @Override
    public void deleteTask(Long taskId) {
        baseMapper.deleteById(taskId);
    }

    @Override
    public CheckTaskResponse.TaskProgress getTaskProgress(Long taskId) {
        if (taskId == null) {
            throw new IllegalArgumentException("任务ID不能为空");
        }
        
        log.debug("查询任务进度，taskId: {}, 类型: {}", taskId, taskId.getClass().getSimpleName());
        CheckTask entity = baseMapper.selectById(taskId);
        log.debug("查询结果: {}", entity != null ? "找到任务" : "未找到任务");
        
        if (entity == null) {
            // 尝试查询最近创建的任务来调试
            log.debug("任务不存在，尝试查询所有任务来调试，taskId: {}", taskId);
            List<CheckTask> allTasks = baseMapper.selectList(null);
            log.debug("数据库中所有任务数量: {}", allTasks.size());
            for (CheckTask task : allTasks) {
                log.debug("  - taskId: {}, 类型: {}", task.getTaskId(), task.getTaskId().getClass().getSimpleName());
            }
            throw new IllegalArgumentException("任务不存在，taskId: " + taskId);
        }
        
        CheckTaskResponse.TaskProgress progress = new CheckTaskResponse.TaskProgress();
        // 设置任务状态 - 转换为小写以匹配前端期望
        String statusLowerCase = entity.getStatus().toLowerCase();
        progress.setStatus(statusLowerCase);
        progress.setCheckedTables(entity.getCheckedTables() != null ? entity.getCheckedTables() : 0);
        progress.setTotalTables(entity.getTotalTables() != null ? entity.getTotalTables() : 1);
        progress.setCheckedRecords(entity.getCheckedRecords() != null ? entity.getCheckedRecords() : 0L);
        progress.setTotalRecords(entity.getTotalRecords() != null ? entity.getTotalRecords() : 0L);
        progress.setFoundIssues(entity.getFoundIssues() != null ? entity.getFoundIssues() : 0);
        
        // 使用数据库中的进度百分比，如果没有则计算
        int progressPercentage = entity.getProgressPercentage() != null ? entity.getProgressPercentage() : 0;
        if (progressPercentage == 0) {
            if ("completed".equals(statusLowerCase)) {
                progressPercentage = 100;
            } else if ("running".equals(statusLowerCase)) {
                if (entity.getTotalTables() != null && entity.getTotalTables() > 0) {
                    progressPercentage = (entity.getCheckedTables() != null ? entity.getCheckedTables() : 0) * 100 / entity.getTotalTables();
                } else {
                    progressPercentage = 50; // 运行中默认50%
                }
            }
        }
        progress.setProgress(progressPercentage);
        progress.setPercentage(progressPercentage); // 前端期望的字段名
        
        // 设置状态消息
        String message = switch (statusLowerCase) {
            case "pending" -> "任务待执行";
            case "running" -> "正在检查敏感词...";
            case "completed" -> "检查完成";
            case "failed" -> "检查失败";
            default -> "";
        };
        progress.setMessage(message);
        
        // 计算已用时间
        if (entity.getStartTime() != null) {
            LocalDateTime endTime = entity.getEndTime() != null ? entity.getEndTime() : LocalDateTime.now();
            progress.setElapsedTime(Duration.between(entity.getStartTime(), endTime).toSeconds());
        }
        
        log.debug("数据库任务状态: {} -> 返回给前端: {}", entity.getStatus(), statusLowerCase);
        return progress;
    }

    @Override
    public void updateTaskProgress(Long taskId, Integer progress, Integer checkedTables, 
                                  Long checkedRecords, Integer foundIssues) {
        CheckTask entity = baseMapper.selectById(taskId);
        if (entity != null) {
            entity.setProgressPercentage(progress);
            entity.setCheckedTables(checkedTables);
            entity.setFoundIssues(foundIssues);
            baseMapper.updateById(entity);
        }
    }

    @Override
    public List<CheckTaskResponse> getRunningTasks() {
        // 简化实现
        return new ArrayList<>();
    }

    @Override
    public List<CheckTaskResponse> getPendingTasks() {
        // 简化实现
        return new ArrayList<>();
    }

    @Override
    public void handleTimeoutTasks(int timeoutMinutes) {
        LocalDateTime timeoutThreshold = LocalDateTime.now().minusMinutes(timeoutMinutes);
        
        // 查询超时的运行中任务
        List<CheckTask> timeoutTasks = baseMapper.selectList(
            new QueryWrapper<CheckTask>()
                .eq("status", "RUNNING")
                .lt("start_time", timeoutThreshold)
        );
        
        for (CheckTask task : timeoutTasks) {
            log.warn("处理超时任务: {}, 启动时间: {}", task.getTaskId(), task.getStartTime());
            
            // 尝试取消正在运行的任务
            Future<?> taskFuture = runningTasks.get(task.getTaskId());
            if (taskFuture != null && !taskFuture.isDone()) {
                taskFuture.cancel(true);
                runningTasks.remove(task.getTaskId());
            }
            
            // 更新任务状态为超时失败
            task.setStatus("FAILED");
            task.setEndTime(LocalDateTime.now());
            task.setErrorMessage("任务执行超时 (" + timeoutMinutes + "分钟)");
            baseMapper.updateById(task);
        }
        
        if (!timeoutTasks.isEmpty()) {
            log.info("处理了{} 个超时任务", timeoutTasks.size());
        }
    }
    
    /**
     * 定时处理超时任务 - 每分钟执行一次
     */
    @Scheduled(fixedRate = 300000) // 300000毫秒 = 5分钟
    public void handleTimeoutTasksScheduled() {
        try {
            handleTimeoutTasks(30); // 处理30分钟超时的任务
        } catch (Exception e) {
            log.error("定时处理超时任务时发生异常: {}", e.getMessage(), e);
        }
    }
    
    /**
     * 定时清理旧任务 - 每天凌晨2点执行
     */
    @Scheduled(cron = "0 0 2 * * ?")
    public void cleanupOldTasks() {
        try {
            LocalDateTime cleanupThreshold = LocalDateTime.now().minusDays(7);
            
            // 删除7天前的已完成或失败的任务
            int deletedCount = baseMapper.delete(
                new QueryWrapper<CheckTask>()
                    .in("status", "COMPLETED", "FAILED", "STOPPED")
                    .lt("end_time", cleanupThreshold)
            );
            
            if (deletedCount > 0) {
                log.info("定时清理任务完成，删除了 {} 个旧任务", deletedCount);
            }
            
            // 清理对应的检查结果（如果有关联的话）
            cleanupOldCheckResults(cleanupThreshold);
            
        } catch (Exception e) {
            log.error("定时清理旧任务时发生异常: {}", e.getMessage(), e);
        }
    }
    
    /**
     * 清理旧的检查结果
     */
    private void cleanupOldCheckResults(LocalDateTime threshold) {
        try {
            // 查询需要清理的任务ID
            List<CheckTask> oldTasks = baseMapper.selectList(
                new QueryWrapper<CheckTask>()
                    .select("task_id")
                    .lt("create_time", threshold)
            );
            
            if (!oldTasks.isEmpty()) {
                List<Long> taskIds = oldTasks.stream()
                    .map(CheckTask::getTaskId)
                    .toList();
                
                // 批量删除相关的检查结果
                for (Long taskId : taskIds) {
                    try {
                        checkResultService.remove(
                            new QueryWrapper<CheckResult>()
                                .eq("task_id", taskId)
                        );
                    } catch (Exception e) {
                        log.error("清理任务 {} 的检查结果时出错: {}", taskId, e.getMessage());
                    }
                }
                
                log.info("清理了{} 个任务的相关检查结果", taskIds.size());
            }
        } catch (Exception e) {
            log.error("清理检查结果时发生异常: {}", e.getMessage(), e);
        }
    }
    
    /**
     * 手动触发清理操作 - 供管理员调用
     */
    public void manualCleanup(int days) {
        LocalDateTime threshold = LocalDateTime.now().minusDays(days);
        
        // 清理指定天数前的任务
        int deletedTasks = baseMapper.delete(
            new QueryWrapper<CheckTask>()
                .in("status", "COMPLETED", "FAILED", "STOPPED")
                .lt("end_time", threshold)
        );
        
        // 清理检查结果
        cleanupOldCheckResults(threshold);
        
        log.info("手动清理完成，删除了 {} 个任务", deletedTasks);
    }
    
    /**
     * 获取系统健康状态
     */
    public SystemHealth getSystemHealth() {
        SystemHealth health = new SystemHealth();
        
        // 线程池状态
        health.setThreadPoolActive(checkExecutor.getActiveCount());
        health.setThreadPoolSize(checkExecutor.getPoolSize());
        health.setThreadPoolQueueSize(checkExecutor.getQueue().size());
        
        // 运行中任务数量
        health.setRunningTasksCount(runningTasks.size());
        
        // 数据库中各状态任务数量
        long runningCount = baseMapper.selectCount(
            new QueryWrapper<CheckTask>()
                .eq("status", "RUNNING")
        );
        health.setDbRunningTasksCount((int) runningCount);
        
        long pendingCount = baseMapper.selectCount(
            new QueryWrapper<CheckTask>()
                .eq("status", "PENDING")
        );
        health.setDbPendingTasksCount((int) pendingCount);
        
        return health;
    }
    
    /**
     * 系统健康状态类
     */
    @Data
    public static class SystemHealth {
        private int threadPoolActive;
        private int threadPoolSize;
        private int threadPoolQueueSize;
        private int runningTasksCount;
        private int dbRunningTasksCount;
        private int dbPendingTasksCount;
        
        public String getStatus() {
            if (threadPoolActive > threadPoolSize * 0.8) {
                return "BUSY";
            } else if (runningTasksCount != dbRunningTasksCount) {
                return "INCONSISTENT";
            } else {
                return "HEALTHY";
            }
        }
    }

    @Override
    public TaskStatistics getTaskStatistics(int days) {
        TaskStatistics stats = new TaskStatistics();
        stats.setTotalTasks(0);
        stats.setCompletedTasks(0);
        stats.setFailedTasks(0);
        stats.setRunningTasks(0);
        return stats;
    }
    
    /**
     * 敏感词信息内部类，用于JSON序列化
     */
    @Data
    private static class KeywordInfo {
        private Long id;
        private String word;
        private String category;
        private Integer level;
    }
    
    /**
     * 检查配置内部类
     */
    @Data
    private static class CheckConfig {
        private Boolean caseSensitive = false;
        private Boolean fuzzyMatch = false;
        private Integer maxResults = 10000;
        private Integer contextLength = 50;
        private Boolean includeDeleted = false;
        private Integer batchSize = 1000;
        private Integer concurrency = 3;
        private Integer timeout = 30;
    }
    
    /**
     * 执行真实的敏感词检查（使用高级配置和并发处理）
     */
    private void executeRealCheck(Long taskId) {
        CheckTask task = baseMapper.selectById(taskId);
        if (task == null) return;
        
        final long startTime = System.currentTimeMillis();
        
        try {
            // 解析选中的关键词
            List<KeywordInfo> keywords = objectMapper.readValue(
                task.getSelectedKeywords(), 
                objectMapper.getTypeFactory().constructCollectionType(List.class, KeywordInfo.class)
            );
            
            // 解析选中的表
            List<String> tables = objectMapper.readValue(
                task.getSelectedTables(),
                objectMapper.getTypeFactory().constructCollectionType(List.class, String.class)
            );
            
            // 解析检查配置
            CheckConfig config = objectMapper.readValue(
                task.getCheckConfig(),
                CheckConfig.class
            );
            
            // 更新总表数
            task.setTotalTables(tables.size());
            task.setCheckedTables(0);
            task.setProgressPercentage(0);
            baseMapper.updateById(task);
            
            // 使用并发处理多个表
            List<CheckResult> allResults = processConcurrentCheck(taskId, tables, keywords, config);
            
            // 批量保存检查结果（分批处理避免内存问题）
            if (!allResults.isEmpty()) {
                saveBatchResults(allResults, config.getBatchSize());
            }
            
            // 更新任务为完成状态
            task.setStatus("COMPLETED");
            task.setEndTime(LocalDateTime.now());
            task.setFoundIssues(allResults.size());
            task.setProgressPercentage(100);
            task.setCheckedRecords((long) allResults.size());
            task.setTotalRecords((long) allResults.size());
            
            // 计算执行时间
            long elapsedTime = (System.currentTimeMillis() - startTime) / 1000;
            task.setElapsedTime(elapsedTime);
            
            baseMapper.updateById(task);
            
            log.info("任务完成，taskId: {}, 状态: COMPLETED, 发现问题: {}, 用时: {}秒", 
                    taskId, allResults.size(), elapsedTime);
            
        } catch (Exception e) {
            throw new RuntimeException("执行敏感词检查失败", e);
        }
    }
    
    /**
     * 并发处理检查任务
     */
    private List<CheckResult> processConcurrentCheck(Long taskId, List<String> tables, 
                                                    List<KeywordInfo> keywords, CheckConfig config) {
        List<CheckResult> allResults = new ArrayList<>();
        AtomicInteger completedTables = new AtomicInteger(0);
        
        // 使用类级别的线程池，不再创建新的线程池
        List<Future<List<CheckResult>>> futures = new ArrayList<>();
        
        try {
            // 为每个表创建检查任务
            for (String tableName : tables) {
                Future<List<CheckResult>> future = checkExecutor.submit(() -> {
                    List<CheckResult> tableResults = new ArrayList<>();
                    
                    if ("sensitive_word".equals(tableName)) {
                        tableResults = checkSensitiveWordTableConcurrent(taskId, keywords, config);
                    }
                    
                    // 更新进度
                    int completed = completedTables.incrementAndGet();
                    updateProgress(taskId, completed, tables.size());
                    
                    // 模拟处理时间（根据配置调整）
                    try {
                        Thread.sleep(500); // 减少延迟，更真实
                    } catch (InterruptedException e) {
                        Thread.currentThread().interrupt();
                    }
                    
                    return tableResults;
                });
                futures.add(future);
            }
            
            // 收集所有结果
            for (Future<List<CheckResult>> future : futures) {
                try {
                    List<CheckResult> tableResults = future.get(config.getTimeout(), TimeUnit.MINUTES);
                    allResults.addAll(tableResults);
                } catch (TimeoutException e) {
                    throw new RuntimeException("检查任务超时", e);
                } catch (ExecutionException e) {
                    throw new RuntimeException("检查任务执行失败", e.getCause());
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    throw new RuntimeException("检查任务被中断", e);
                }
            }
            
        } finally {
            // 不需要关闭类级别的线程池，它会在应用关闭时自动销毁
            // checkExecutor 会在 @PreDestroy 方法中统一清理
        }
        
        return allResults;
    }
    
    /**
     * 更新任务进度
     */
    private void updateProgress(Long taskId, int completedTables, int totalTables) {
        CheckTask task = baseMapper.selectById(taskId);
        if (task != null) {
            task.setCheckedTables(completedTables);
            int progress = completedTables * 100 / totalTables;
            task.setProgressPercentage(progress);
            baseMapper.updateById(task);
        }
    }
    
    /**
     * 分批保存结果
     */
    private void saveBatchResults(List<CheckResult> results, int batchSize) {
        for (int i = 0; i < results.size(); i += batchSize) {
            int endIndex = Math.min(i + batchSize, results.size());
            List<CheckResult> batch = results.subList(i, endIndex);
            
            for (CheckResult result : batch) {
                checkResultService.save(result);
            }
        }
    }
    
    /**
     * 并发检查sensitive_word表
     */
    private List<CheckResult> checkSensitiveWordTableConcurrent(Long taskId, List<KeywordInfo> keywords, CheckConfig config) {
        List<CheckResult> results = new ArrayList<>();
        
        // 获取所有敏感词记录 - 考虑分页查询避免内存溢出
        List<SensitiveWord> allWords = sensitiveWordMapper.selectList(null);
        
        // 根据批处理大小分批处理
        for (int i = 0; i < allWords.size(); i += config.getBatchSize()) {
            int endIndex = Math.min(i + config.getBatchSize(), allWords.size());
            List<SensitiveWord> batch = allWords.subList(i, endIndex);
            
            List<CheckResult> batchResults = processBatch(taskId, batch, keywords, config);
            results.addAll(batchResults);
            
            // 限制最大结果数
            if (results.size() >= config.getMaxResults()) {
                break;
            }
        }
        
        return results;
    }
    
    /**
     * 处理批次数据
     */
    private List<CheckResult> processBatch(Long taskId, List<SensitiveWord> words, 
                                          List<KeywordInfo> keywords, CheckConfig config) {
        List<CheckResult> results = new ArrayList<>();
        
        for (SensitiveWord word : words) {
            for (KeywordInfo keyword : keywords) {
                // 根据配置判断是否匹配
                boolean matches = false;
                if (config.getCaseSensitive()) {
                    matches = word.getWord() != null && word.getWord().contains(keyword.getWord());
                } else {
                    matches = word.getWord() != null && 
                             word.getWord().toLowerCase().contains(keyword.getWord().toLowerCase());
                }
                
                if (matches) {
                    CheckResult result = createCheckResult(taskId, word, keyword, config);
                    results.add(result);
                }
            }
        }
        
        return results;
    }
    
    /**
     * 创建检查结果
     */
    private CheckResult createCheckResult(Long taskId, SensitiveWord word, KeywordInfo keyword, CheckConfig config) {
        CheckResult result = new CheckResult();
        result.setTaskId(taskId);
        result.setDatabaseName("demo");
        result.setTableName("sensitive_word");
        result.setColumnName("word");
        result.setRecordId(word.getId().toString());
        result.setSensitiveWord(keyword.getWord());
        
        // 根据配置设置上下文长度
        String context = String.format("在敏感词库中发现: %s (类别: %s, 等级: %d)", 
                                      word.getWord(), keyword.getCategory(), keyword.getLevel());
        if (config.getContextLength() > 0 && context.length() > config.getContextLength()) {
            context = context.substring(0, config.getContextLength()) + "...";
        }
        result.setContext(context);
        
        result.setSuggestion("检查此敏感词是否需要保留或清理");
        result.setProcessStatus("PENDING");
        result.setFindTime(LocalDateTime.now());
        
        return result;
    }
    
    /**
     * 销毁方法，清理线程池资源
     */
    @PreDestroy
    public void destroy() {
        // 取消所有运行中的任务
        for (Future<?> future : runningTasks.values()) {
            if (!future.isDone()) {
                future.cancel(true);
            }
        }
        runningTasks.clear();
        
        // 关闭线程池
        if (checkExecutor != null && !checkExecutor.isShutdown()) {
            checkExecutor.shutdown();
            try {
                if (!checkExecutor.awaitTermination(30, TimeUnit.SECONDS)) {
                    checkExecutor.shutdownNow();
                    // 再次等待一段时间，确保线程完全停止
                    if (!checkExecutor.awaitTermination(5, TimeUnit.SECONDS)) {
                        log.warn("线程池无法在规定时间内完全关闭");
                    }
                }
            } catch (InterruptedException e) {
                checkExecutor.shutdownNow();
                Thread.currentThread().interrupt();
            }
        }
    }
}
